package com.gopay.common.util;


import com.gopay.common.model.ExportDataModel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.SftpException;
import org.apache.log4j.Logger;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;


/**
 * 文件操作
 * @TXTUtils.java
 * @author jianghp
 * @2016年7月15日 上午11:04:52  www.gopay.com.cn Inc.All rights reserved.
 */
public class TXTUtils {
    private static final Logger log = Logger.getLogger(SftpChannel.class.getName());
    private static SimpleDateFormat simpleDateFormt = new SimpleDateFormat("yyyyMMddHHmmss");
    private static final String LINE = "\r\n";//System.getProperty("line.separator");
    private static final String PREFIX_PATH = "/usr/local/ciecc/webapps/upload/fund/tmp";

    public static Boolean uploadSftpZip(ExportDataModel txtExportModel,String fileName,String ftpPath,String name,String pwd,String IP,Integer port,Integer timeOut) {
        Boolean flag = true;
        File file = null;
        File zipFile = null;
        String path= PREFIX_PATH + File.separator +fileName+".txt";
        try{
            File prefixFile = new File(PREFIX_PATH);
            if (!prefixFile.exists()) {
                prefixFile.mkdirs();
            }
            file = new File(path);
            StringBuilder stringBuilder = constructStringByModel(txtExportModel);
            ZipFileUtils bean = new ZipFileUtils();
            String innerText =stringBuilder.toString();
            FileUtil.writeTxtFile(innerText,file);
            bean.zip(path,path+".zip");

            ChannelSftp chSftp = SftpChannel.getChannel(IP,port,name,pwd,timeOut);
            SftpUtil.upload(ftpPath, path +".zip", chSftp);
            chSftp.quit();
            SftpChannel.closeChannel();
            zipFile = new File(path +".zip");
        }catch (Exception e){
            flag = false;
            log.error("TXTUtils文件上传sftp异常",e);
        }finally {
            if(null!=file){
                file.delete();
            }
            if(null!=zipFile){
                zipFile.delete();
            }
        }
        return flag;
    }
    public static Boolean uploadSftpZip2(ExportDataModel txtExportModel,String fileName,String ftpPath,String name,String pwd,String fileDate, String cdPath,String IP,Integer port,Integer timeOut) {
        Boolean flag = true;
        File file = null;
        File zipFile = null;
        String path= PREFIX_PATH + File.separator +fileName+".txt";
        try{
            File prefixFile = new File(PREFIX_PATH);
            if (!prefixFile.exists()) {
                prefixFile.mkdirs();
            }
            file = new File(path);
            StringBuilder stringBuilder = constructStringByModel(txtExportModel);
            ZipFileUtils bean = new ZipFileUtils();
            String innerText =stringBuilder.toString();
            FileUtil.writeTxtFile(innerText,file);
            bean.zip(path,path+".zip");

            ChannelSftp chSftp = SftpChannel.getChannel(IP,port,name,pwd,timeOut);
            chSftp.cd(cdPath);
            String pwd1 = chSftp.pwd();
            upload(ftpPath, path + ".zip", chSftp, fileDate, cdPath);
            chSftp.quit();
            SftpChannel.closeChannel();
            zipFile = new File(path +".zip");
        }catch (Exception e){
            flag = false;
            log.error("TXTUtils文件上传sftp异常",e);
        }finally {
            if(null!=file){
                file.delete();
            }
            if(null!=zipFile){
                zipFile.delete();
            }
        }
        return flag;
    }


    public static Boolean uploadSftpZipForRedeem(ExportDataModel txtExportModel,String fileName,String ftpPath,String name,String pwd,String fileDate, String cdPath,String IP,Integer port,Integer timeOut) throws Exception {
        Boolean flag = true;
        File file = null;
        File zipFile = null;
        String path= PREFIX_PATH + File.separator +fileName+".txt";
        try{
            File prefixFile = new File(PREFIX_PATH);
            if (!prefixFile.exists()) {
                prefixFile.mkdirs();
            }
            file = new File(path);
            StringBuilder stringBuilder = constructStringByModel(txtExportModel);
            ZipFileUtils bean = new ZipFileUtils();
            String innerText =stringBuilder.toString();
            FileUtil.writeTxtFile(innerText,file);
            bean.zip(path,path+".zip");

            ChannelSftp chSftp = SftpChannel.getChannel(IP,port,name,pwd,timeOut);
            chSftp.cd(cdPath);
            String pwd1 = chSftp.pwd();
            upload2(ftpPath, path + ".zip", chSftp, fileDate, cdPath);
            chSftp.quit();
            SftpChannel.closeChannel();
            zipFile = new File(path +".zip");
        }catch (Exception e){
            flag = false;
            log.error("TXTUtils文件上传sftp异常",e);
        }finally {
            if(null!=file){
                file.delete();
            }
            if(null!=zipFile){
                zipFile.delete();
            }
        }
        return flag;
    }


    public static void upload(String directory, String uploadFile, ChannelSftp sftp,String fileDate,String cdPath) {
        String[] split = directory.split("/");
        for (String s : split) {
            try {
                sftp.cd(s);
            } catch (SftpException sException) {
                if(sftp.SSH_FX_NO_SUCH_FILE == sException.id){
                    try {
                        sftp.mkdir(s);
                        sftp.cd(s);
                    } catch (Exception e) {
                        log.error("=====create folder error>"+e.getMessage());
                    }
                }
            }
        }
        FileInputStream is = null;
        try {
            //sftp.getHome();
            log.info("=====Current path is>" + sftp.pwd());
            sftp.cd(cdPath+"/"+fileDate);
            File file = new File(uploadFile);
            is = new FileInputStream(file);
            sftp.put(is, file.getName());
            log.info("=====sftp upload success>" + file.getName());
        } catch (Exception e) {
            log.error("=====sftp upload error>"+e.getMessage(),e);
        }finally {
            if(is != null){
                try {
                    is.close();
                } catch (IOException e) {
                    log.error("=====FileInputStream close error>"+e.getMessage(),e);
                }
            }
        }
    }

    public static void upload2(String directory, String uploadFile, ChannelSftp sftp,String fileDate,String cdPath) throws SftpException {
        String[] split = directory.split("/");
        for (String s : split) {
            sftp.cd(s);
        }
        FileInputStream is = null;
        try {
            //sftp.getHome();
            log.info("=====Current path is>" + sftp.pwd());
            sftp.cd(cdPath+"/"+fileDate);
            File file = new File(uploadFile);
            is = new FileInputStream(file);
            sftp.put(is, file.getName());
            log.info("=====sftp upload success>" + file.getName());
        } catch (Exception e) {
            log.error("=====sftp upload error>"+e.getMessage(),e);
        }finally {
            if(is != null){
                try {
                    is.close();
                } catch (IOException e) {
                    log.error("=====FileInputStream close error>"+e.getMessage(),e);
                }
            }
        }
    }


    /**
     * @param request
     * @param response
     * @param txtExportModel
     * @param downFileName
     * 普通下载模板
     */
    public static void export(HttpServletRequest request, HttpServletResponse response, ExportDataModel txtExportModel, String downFileName) {
        File file = null;
        try{
            file = constructTempFile();
            StringBuilder stringBuilder = constructStringByModel(txtExportModel);
            dataToTempFile(stringBuilder,file);
            response.reset();
            response.setContentType("text/x-plain");
            write2Respose(file, response,processFileName(request,downFileName));
        }finally {
            if(null!=file){
                file.delete();
            }
        }

    }

    /**
     * @param request
     * @param response
     * @param stringBuilder
     * @param downFileName
     * 定制下载，调用方需要自己拼下载内容，在通过该接口调用
     */
    public static void exportByString(HttpServletRequest request,HttpServletResponse response,StringBuilder stringBuilder,String downFileName){
        File file = null;
        try{
            file = constructTempFile();
            dataToTempFile(stringBuilder,file);
            response.reset();
            response.setContentType("application/x-rarx-rar-compressed");
            response.setCharacterEncoding("GBK");
            write2Respose(file, response,downFileName);
        }finally {
            if(null!=file){
                file.delete();
            }

        }
    }

    /**
     * 构造临时文件
     *
     * @return String
     */
    private static File constructTempFile() {
        String path = System.getProperty("java.io.tmpdir") + File.separator + "tmp" + simpleDateFormt.format(new Date()) + ".txt";
        File file = new File(path);
        return file;
    }

    /**
     * @param txtExportModel
     * @return
     * 通过模型类构造字符串
     */

    private static StringBuilder constructStringByModel(ExportDataModel txtExportModel){
        StringBuilder sb = new StringBuilder();
        if(txtExportModel.getInfoOrCountS().size()!=0) {
            List<Map<String, Object>> infoOrCountS = txtExportModel.getInfoOrCountS();
            //输出统计说明信息
            if (null != infoOrCountS && infoOrCountS.size() > 0) {
                for (Map<String, Object> infoOrCount : infoOrCountS) {
                    Set<String> keySet = infoOrCount.keySet();
                    if (null != keySet && keySet.size() > 0) {
                        for (String key : keySet) {
                            sb.append(key).append(":").append(infoOrCount.get(key).toString()).append("|");
                        }
                    }
                }
            }
            sb = new StringBuilder(sb.substring(0, sb.length() - 1));
            sb.append(LINE);
        }
        //输出明细数据信息
        List<Object> detailHeadList = txtExportModel.getDetailHeadList();
        if (null != detailHeadList && detailHeadList.size() > 0) {
            for (Object object : detailHeadList) {
                sb.append(object.toString()).append("|");
            }
            sb = new StringBuilder(sb.substring(0,sb.length()-1));
            sb.append(LINE);
        }
        List<List<Object>> detailInfoS = txtExportModel.getDetailInfoSList();
        for (List<Object> detailInfo : detailInfoS) {
            if (null != detailInfo && detailInfo.size() > 0) {
                for (Object object : detailInfo) {
                    sb.append(object!= null?object.toString():"").append("|");
                }
                sb = new StringBuilder(sb.substring(0,sb.length()-1));
                sb.append(LINE);
            }
        }
        return sb;
    }

    /**
     * 数据写入临时文件
     *
     * @param stringBuilder
     * @param file
     */
    private static void dataToTempFile(StringBuilder stringBuilder, File file) {

        //写入文件
        FileOutputStream fos = null;
        Writer writer = null;
        try {
            fos = new FileOutputStream(file);
            writer = new OutputStreamWriter(fos, "GBK");
            writer.write(stringBuilder.toString());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (null != writer) {
                try {
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * @param file
     * @param response 写数据流到客户端供下载
     */
    private static void write2Respose(File file, HttpServletResponse response,String downFileName) {
        response.setHeader("Content-disposition", "attachment; filename=" + downFileName);// 设定输出文件头
        ServletOutputStream out = null;
        FileInputStream fis = null;
        try {
            out = response.getOutputStream();
            fis = new FileInputStream(file);
            ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream(4096);
            byte[] cache = new byte[4096];
            for (int offset = fis.read(cache); offset != -1; offset = fis.read(cache)) {
                byteOutputStream.write(cache, 0, offset);
            }
            byte[] bt = null;
            bt = byteOutputStream.toByteArray();
            out.write(bt);
            out.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != out) {
                    out.close();
                }
                if (null != fis) {
                    fis.close();
                }
                if (file.exists()) {
                    file.delete();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     *
     * @param request
     * @param fileNames
     * @return
     * 解析调用者传送的文件名，以防止乱码
     */
    private static String processFileName(HttpServletRequest request, String fileNames) {
        String codedfilename = null;
        try {
            String agent = request.getHeader("USER-AGENT");
            if (null != agent && -1 != agent.indexOf("MSIE") || null != agent
                    && -1 != agent.indexOf("Trident")) {// ie
                String name = java.net.URLEncoder.encode(fileNames, "UTF8");
                codedfilename = name;
            } else if (null != agent && -1 != agent.indexOf("Mozilla")) {// 火狐,chrome等
                codedfilename = new String(fileNames.getBytes("UTF-8"), "iso-8859-1");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return codedfilename;
    }
}
